
import banco.*;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;

public class Cliente {

    private static java.io.BufferedReader reader;
    private static caixa_eletronico server;
    private static int conta;
    public static final int SALDO = 1;
    public static final int EXTRATO = 2;
    public static final int SAQUE = 3;
    public static final int TRANSFERENCIA = 4;
    public static final int INVESTIMENTO = 5;
    public static final int SAIR = 6;
    public static final int POUPANCA = 1;
    public static final int FUNDO_ACOES = 2;
    public static final int RENDA_FIXA = 3;
    public static final int CANCELAR = 4;

    public static void main(String args[]) {
        /* Inicializa entrada do usuario */
        reader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));

        try {
            // Cria e inicializa o ORB
            ORB orb = ORB.init(args, null);

            // Obtem referencia para o servico de nomes
            org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
            NamingContextExt ncRef =
                    NamingContextExtHelper.narrow(objRef);

            // Obtem referencia para o servidor
            String name = "CaixaEletronico";
            server = caixa_eletronicoHelper.narrow(ncRef.resolve_str(name));
            //server = auto_atendimentoHelper.narrow(ncRef.resolve_str(name));

            int opcao;

            /* Imprime mensagem de boas-vindas */
            System.out.println("=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*");
            System.out.println(server.boas_vindas());
            System.out.println("=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*");

            do {

                /* Obtem o numero da conta */
                System.out.print("Entre o numero da sua conta: ");
                conta = Integer.parseInt(reader.readLine());

                /* Imprime opcoes disponiveis */
                System.out.println("------------- Opcoes -------------");
                System.out.println(Integer.toString(SALDO) + " - Consulta de saldo.");
                System.out.println(Integer.toString(EXTRATO) + " - Consulta de extrato.");
                System.out.println(Integer.toString(SAQUE) + " - Operacao de saque.");
                System.out.println(Integer.toString(TRANSFERENCIA) + " - Operação de transferencia.");
                System.out.println(Integer.toString(INVESTIMENTO) + " - Investimentos.");
                System.out.println(Integer.toString(SAIR) + " - Sair.");
                System.out.println("----------------------------------");
                System.out.print("Entre com a opcao desejada: ");
                opcao = Integer.parseInt(reader.readLine());

                try {
                    /* Trata opcao escolhida */
                    switch (opcao) {
                        case SALDO:
                            saldo();
                            break;
                        case EXTRATO:
                            extrato();
                            break;
                        case SAQUE:
                            saque();
                            break;
                        case TRANSFERENCIA:
                            transferencia();
                            break;
                        case INVESTIMENTO:
                            investimento();
                            break;
                        case SAIR:
                            break;
                        default:
                            System.out.println("Opcao invalida: por favor entre com uma opcao valida.");
                    }

                } catch (banco.conta_inval e) {
                    System.out.println("Conta inexistente: por favor entre com uma conta valida.");
                } catch (banco.saldo_insuf e) {
                    System.out.println("Saldo insuficiente: por favor consulte seu saldo antes de executar a operacao.");
                }
            } while (opcao != SAIR);

        } catch (Exception e) {
            System.out.println("ERROR : " + e);
            e.printStackTrace(System.out);
        }
    }

    /**
    Saldo
     */
    private static void saldo() throws banco.conta_inval {
        double saldo;

        saldo = server.saldo(conta);    // chamada remota

        if (saldo == -99) {
            throw new conta_inval();
        } else {
            System.out.print("Saldo atual: R$ ");
            System.out.println(saldo);
        }
    }

    /**
    Extrato
     */
    private static void extrato() throws banco.conta_inval {
        transacoesHolder transacoes = new transacoesHolder();
        org.omg.CORBA.DoubleHolder saldo = new org.omg.CORBA.DoubleHolder();

        System.out.println("-------- ANTES --------");
        System.out.println(conta);
        System.out.println(saldo.value);

        server.extrato(conta, transacoes, saldo); // Chamada remota onde acontece o erro.

        System.out.println("-------- DEPOIS --------");

        if (transacoes == null) {
            System.out.println("Transação nula.");
        } else {
            if (transacoes.value.length <= 0) {
                System.out.println(" <IGUAL A ZERO");
            } else {
                System.out.println(" MAIOR");
            }
        }
    /* Imprime transacoes */
                System.out.println("-------- extrato --------");
                for (int c = 0; c < transacoes.value.length; c++)
                {
                        System.out.print(transacoes.value[c].data);
                        System.out.print(" - " + transacoes.value[c].descricao + " - R$ ");
                        System.out.println(transacoes.value[c].quantia);
                }
                System.out.println("-------------------------");
                System.out.println("Saldo atual: R$ " + saldo.value);                
    }

    /**
    Saque
     */
    private static void saque() throws banco.conta_inval, banco.saldo_insuf, java.io.IOException {
        /* Pede pelo valor */
        System.out.print("Entre com o valor para efetuar o saque: R$ ");
        double valor = Double.parseDouble(reader.readLine());

        server.saque(conta, valor); // Chamada remota

        /* Escreve o dinheiro */
        System.out.println("Saque efetuado. aguarde, contanto notas...");
    }

    /**
    Transferencia
     */
    private static void transferencia() throws banco.conta_inval, banco.saldo_insuf, java.io.IOException {
        /* Pede pela conta de destino */
        System.out.print("Entre o numero da conta de destino(favorecido): ");
        int destino = Integer.parseInt(reader.readLine());

        /* Pede pelo valor */
        System.out.print("Entre com o valor para transferencia: R$ ");
        double valor = Double.parseDouble(reader.readLine());

        server.tranferencia(conta, destino, valor); // Chamada remota

        /* Imprime estatus */
        System.out.println("Transferencia bem sucedida.");
    }

    /**
    Investimento
     */
    private static void investimento() throws banco.conta_inval, banco.saldo_insuf, java.io.IOException {
        double valor;

        /* Imprime opcoes de investimento */
        System.out.println("-------- opcoes de investimento --------");
        System.out.println(Integer.toString(POUPANCA) + " - Fundo de poupanca.");
        System.out.println(Integer.toString(FUNDO_ACOES) + " - Fundo de acoes.");
        System.out.println(Integer.toString(RENDA_FIXA) + " - Fundo de renda fixa.");
        System.out.println(Integer.toString(CANCELAR) + " - Cancelar investimento.");
        System.out.println("----------------------------------------");
        System.out.print("Entre com a opcao de investimento desejado: ");
        int investimento = Integer.parseInt(reader.readLine());

        switch (investimento) {
            case POUPANCA:
                /* Pede pelo valor */
                System.out.print("Entre com o valor de investimento na poupanca: R$ ");
                valor = Double.parseDouble(reader.readLine());
                server.investimento(conta, aplicacao.poupanca, valor); // chamda remota
                break;
            case FUNDO_ACOES:
                /* Pede pelo valor */
                System.out.print("Entre com o valor de investimento no fundo de acoes: R$ ");
                valor = Double.parseDouble(reader.readLine());
                server.investimento(conta, aplicacao.fundo_acoes, valor); // chamda remota
                break;
            case RENDA_FIXA:
                /* Pede pelo valor */
                System.out.print("Entre com o valor de investimento em renda fixa: R$ ");
                valor = Double.parseDouble(reader.readLine());
                server.investimento(conta, aplicacao.renda_fixa, valor); // chamda remota
                break;
            case CANCELAR:
                return;
            default:
                System.out.println("Opcao de investimento invalida: entre com uma opcao valida.");
                return;
        }

        /* Imprime estatus */
        System.out.println("Investimento efetuado com sucesso.");
    }
}
